﻿#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

typedef double Real;

typedef struct {
	int m;
	int n;
	int data[100000];
}Matrix;

typedef struct
{
	Matrix A;
	Matrix B;
}Context;
Context context;

void matrix_read(Matrix* A)
{
	scanf("%d %d", &A->m, &A->n);
	for (int i = 0, k = 0; i < A->m; ++i)
		for (int j = 0; j < A->n; ++j, ++k)
			scanf("%d", &A->data[k]);
}

void matrix_dump(Matrix* A)
{
	printf("%d %d\n", A->m, A->n);
	for (int i = 0, k = 0; i < A->m; ++i) {
		for (int j = 0; j < A->n; ++j, ++k) {
			if (j > 0)
				printf(" ");
			printf("%d", A->data[k]);
		}
		printf("\n");
	}
}
Matrix* matrix_mul(Matrix* C, Matrix* A, Matrix* B)
{
	if (A->n != B->m)
	{
		printf("Error: %d != %d\n", A->n, B->m);
		return NULL;
	}
	memset(C->data, 0, sizeof(C->data));
	C->m = A->m;
	C->n = B->n;
	for (int i = 0; i < A->m; ++i)
		for (int j = 0; j < B->n; ++j)
			for (int k = 0; k < A->n; ++k)
				C->data[i * C->n + j] += A->data[i * A->n + k] * B->data[k * B->n + j];
	matrix_dump(C);
}

void read_data(Context* ctx)
{
	matrix_read(&ctx->A);
	matrix_read(&ctx->B);
}

void printAB(int A, int B)
{
	printf("%d/", A);
	if (B < 0)
		printf("(%d)", B);
	else
		printf("%d", B);
	printf("=");
}

void solve(Context* ctx)
{
	Matrix C;
	matrix_mul(&C, &ctx->A, &ctx->B);
}

int main()
{
	freopen("D:/Develop/GitRepos/MOOC/浙江大学/数据结构/201906/DataStructure/M2019秋C入门和进阶练习集/7-169.txt", "r", stdin);
	read_data(&context);
	solve(&context);
	return 0;
}
